/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import * as arkts from '@koalaui/libarkts';
import { getAnnotationUsage, getClassPropertyAnnotationNames, PresetDecorators } from '../utils';
import { UISyntaxRule, UISyntaxRuleContext } from './ui-syntax-rule';

function checkLocalStorageLink(node: arkts.StructDeclaration, context: UISyntaxRuleContext): void {
  // Check if @Entry decorator exists with parameter
  const entryDecorator = getAnnotationUsage(node, PresetDecorators.ENTRY);
  const isStorageUsed = entryDecorator && node.definition?.annotations[0].properties[0];
  // Check if @LocalStorageLink exists
  let localStorageLinkUsed = false;
  node.definition.body.forEach(body => {
    if (!arkts.isClassProperty(body)) {
      return;
    }
    const propertyDecorators = getClassPropertyAnnotationNames(body);
    localStorageLinkUsed = propertyDecorators.some(
      decorator => decorator === PresetDecorators.LOCAL_STORAGE_LINK);
  });

  // If @LocalStorageLink is used but @Entry(storage) is missing, report error
  if (entryDecorator && localStorageLinkUsed && !isStorageUsed) {
    context.report({
      node: entryDecorator,
      message: rule.messages.invalidUsage
    });
  }
}

const rule: UISyntaxRule = {
  name: 'entry-localstorage-check',
  messages: {
    invalidUsage: `@LocalStorageLink requires @Entry(storage) on the struct.`,
  },
  setup(context) {
    return {
      parsed: (node): void => {
        if (!arkts.isStructDeclaration(node)) {
          return;
        }
        checkLocalStorageLink(node, context);
      },
    };
  },
};

export default rule;
